package mysql

import (
	"config"
	"fmt"
	"model"
	_ "github.com/go-sql-driver/mysql"
	"github.com/go-xorm/xorm"
)

type Repo struct {
	engine *xorm.Engine
}

func NewRepo(c *config.Config) (model.IRepo, error) {
	engine, err := xorm.NewEngine("mysql", c.GetDatasourceString())
	if err != nil {
		return nil, err
	}
	engine.ShowSQL(c.Debug)
	return &Repo{
		engine: engine,
	}, nil
}


// GetDBs 按条件查询数据库信息
func (repo *Repo) GetDBs(cond *model.DB, lazy bool) (items []model.DB, err error) {
	var sCond =new(Schema)
	if cond != nil {
		sCond.Name = cond.Name
		sCond.CharSet = cond.CharSet
		sCond.Collation = cond.Collation
	}
	schemas, err :=sCond.getSchemas(repo)

	if err != nil {
		fmt.Println(err.Error())
		return nil, err
	}

	if len(schemas) <= 0 {
		return nil, model.ErrDBNotFound
	}

	for i := range schemas {
		var tables []model.Table
		if !lazy {
			tables, err = repo.GetTables(&model.Table{
				DB: schemas[i].Name,
			})
			if err != nil {
				return nil, err
			}
		}
		items = append(items, model.DB{
			Name:      schemas[i].Name,
			CharSet:   schemas[i].CharSet,
			Collation: schemas[i].Collation,
			Tables:    tables,
		})
	}

	return items, nil
}

// GetTables 按条件查询表信息
func (repo *Repo) GetTables(cond *model.Table) (items []model.Table, err error) {
	var tCond =new(Table)
	if cond != nil {
		tCond.Schema = cond.DB
		tCond.Name = cond.Name
		tCond.Collation = cond.Collation
		tCond.Comment = cond.Comment
	}

	tables, err :=tCond.getTables(repo)
	if err != nil {
		return nil, err
	}

	for i := range tables {
		cols, err := repo.GetColumns(&model.Column{
			DB:    tables[i].Schema,
			Table: tables[i].Name,
		})
		if err != nil {
			return nil, err
		}
		items = append(items, model.Table{
			DB:        tables[i].Schema,
			Name:      tables[i].Name,
			Collation: tables[i].Collation,
			Comment:   tables[i].Comment,
			Columns:   cols,
		})
	}
	return items, nil
}

// GetColumns 按条件查询列信息
func (repo *Repo) GetColumns(cond *model.Column) (items []model.Column, err error) {
	var cCond =new(Column)
	if cond != nil {
		cCond.Schema = cond.DB
		cCond.Table = cond.Table
		cCond.Name = cond.Name
		cCond.Default = cond.Default
		cCond.Nullable = cond.Nullable
		cCond.CharSet = cond.CharSet
		cCond.Collation = cond.Collation
		cCond.DataType = cond.DataType
		cCond.Key = cond.Key
		cCond.Comment = cond.Comment
	}
	cols, err :=cCond.getColumns(repo)
	if err != nil {
		return nil, err
	}

	for i := range cols {
		items = append(items, model.Column{
			DB:        cols[i].Schema,
			Table:     cols[i].Table,
			Name:      cols[i].Name,
			Default:   cols[i].Default,
			Nullable:  cols[i].Nullable,
			DataType:  cols[i].DataType,
			Key:       cols[i].Key,
			CharSet:   cols[i].CharSet,
			Collation: cols[i].Collation,
			Comment:   cols[i].Comment,
		})
	}
	return items, nil
}
